package cn.learn.office.pdf;

import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.text.PDFTextStripper;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * https://blog.csdn.net/sciii/article/details/104492574
 * pdf转txt
 *
 * @author huangyezhan
 * @version 1.0
 * @date 2021年01月15日21:49
 */
@Slf4j
public class PdfToTxt {


    public static void main(String[] args) {
        try {
            //取得F盘下的pdf的内容
            String          path            = "E:\\download\\关于2021年春节放假的通知.pdf";
            File            file            = new File(path);
            FileInputStream fileInputStream = new FileInputStream(file);

            /*String          textFromPdf     = getTextFromPdf(fileInputStream, true);
            System.out.println(textFromPdf);*/

            pdf2image(fileInputStream, "E:\\download\\");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void pdf2image(InputStream stream, String imgPath) {
        PDDocument document = null;
        // 加载 pdf 文档
        try {
            document = PDDocument.load(stream);
            PDFRenderer renderer = new PDFRenderer(document);

            int pageCount = document.getNumberOfPages();
            System.out.println("共 " + pageCount + " 页.");
            for (int i = 0; i < pageCount; i++) {
                /*
                 * renderImage(i,1.9f)
                 *
                 * i: 指定页对象下标,从0开始,0即第一页
                 *
                 * 1.9f:DPI值(Dots Per Inch),官方描述比例因子，其中1=72 DPI
                 *      DPI是指每英寸的像素,也就是扫描精度,DPI越低,扫描的清晰度越低
                 *      根据根据自己需求而定,我导出的图片是 927x1372
                 */
                BufferedImage image = renderer.renderImage(i, 1.9f);
                // 导出图片命名为:0-n.jpeg
                ImageIO.write(image, "JPEG", new File(imgPath + i + ".jpeg"));
                System.out.println("导出 " + imgPath + i + ".jpeg...");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从pdf文件中解析为字符串,只能返回pdf中的文字内容，图片，表格均解析不了
     *
     * @param fileStream 流
     * @param sort       是否有序
     * @return 返回结果
     */
    public static String getTextFromPdf(InputStream fileStream, boolean sort) {
        // 开始提取页数
        int startPage = 1;
        // 结束提取页数
        String     content  = null;
        PDDocument document = null;
        try {
            // 加载 pdf 文档
            document = PDDocument.load(fileStream);
            int             endPage  = null == document ? Integer.MAX_VALUE : document.getNumberOfPages();
            PDFTextStripper stripper = new PDFTextStripper();
            stripper.setSortByPosition(sort);
            stripper.setStartPage(startPage);
            stripper.setEndPage(endPage);
            content = stripper.getText(document);
        } catch (Exception e) {
            log.error("文件解析异常，信息为： " + e.getMessage());
        }
        return content;

    }

    /**
     * 从pdf文档中读取所有的图片信息
     *
     * @return 返回结果
     * @throws Exception 异常
     */
    public static List<PDImageXObject> getImageListFromPDF(PDDocument document, Integer startPage) throws Exception {
        List<PDImageXObject> imageList = new ArrayList<>();
        if (null != document) {
            PDPageTree pages = document.getPages();
            startPage = startPage == null ? 0 : startPage;
            int len = pages.getCount();
            if (startPage < len) {
                for (int i = startPage; i < len; i++) {
                    PDPage            page        = pages.get(i);
                    Iterable<COSName> objectNames = page.getResources().getXObjectNames();
                    for (COSName imageObjectName : objectNames) {
                        if (page.getResources().isImageXObject(imageObjectName)) {
                            imageList.add((PDImageXObject) page.getResources().getXObject(imageObjectName));
                        }
                    }
                }
            }
        }
        return imageList;
    }

    /**
     * 注意：上个方法中返回的list中为 PDImageXObject 对象，不是我们Java中对应的Image对象，
     * 所以不能直接保存到本地或者提交到服务器，需要进行简单的转换一下，例子可参考如下：
     * <p>
     * 读取图片文件流信息
     *
     * @param image 图片文件流
     * @return 返回流
     * @throws Exception 异常
     */
    public static InputStream getImageInputStream(PDImageXObject image) throws Exception {

        if (null != image && null != image.getImage()) {
            BufferedImage         bufferImage = image.getImage();
            ByteArrayOutputStream os          = new ByteArrayOutputStream();

            ImageIO.write(bufferImage, image.getSuffix(), os);
            return new ByteArrayInputStream(os.toByteArray());
        }
        return null;
    }
}
